// @Author miaoqing
// @Date 2024/03/01 16:04:00
// @Desc
package logic

import (
	"core/common"
	"core/component/function"
	"core/component/idgenerator"
	"core/component/logger"
	"core/component/timer"
	"core/ini"
	"core/network"
	"net"
	"runtime/debug"
	"strconv"
	"sync"
	"time"
)

const (
	tcpService  = "center-tcp"
	httpService = "center-http"
)

var (
	server *Server
	once   sync.Once
)

type Server struct {
	network.Service
	id         string
	timer      *timer.Timer
	conf       *ini.Config
	tcpServer  *network.TcpServer
	tcpSrvID   string
	tcpSrvPort int
	tcpSrvAddr string

	httpSrvID   string
	httpAddr    string
	httpPort    int
	httpHandler *HTTPHandler
}

func ServerInstance() *Server {
	once.Do(func() {
		server = &Server{
			httpHandler: newHttpHandler(),
			tcpServer:   &network.TcpServer{},
			timer:       timer.NewTimer(),
		}
		server.Impl = server
	})
	return server
}

func (srv *Server) Init(cfg interface{}, processIdx int) {
	c, ok := cfg.(*ini.Config)
	if !ok {
		return
	}
	srv.conf = c
	srv.tcpSrvPort = srv.conf.Server.CenterTcpPort + processIdx
	srv.tcpSrvAddr = srv.conf.Server.CenterTcpIp + ":" + strconv.Itoa(srv.tcpSrvPort)
	srv.tcpServer.Init(srv.tcpSrvAddr)

	srv.httpPort = srv.conf.Server.CenterHttpPort + processIdx
	srv.httpAddr = srv.conf.Server.CenterHttpIp + ":" + strconv.Itoa(srv.httpPort)
	srv.id = strconv.FormatUint(function.IpAddressStringToUint64(srv.httpAddr), 10)

	logger.Infof("CenterID:%v pidx:%v", srv.id, processIdx)
}

func (srv *Server) Run() {
	srv.tcpServer.NewClient = func(conn net.Conn) network.IConn {
		cli := &OnlineClient{
			NetConn: network.NewNetConn(conn, 512*1024),
		}
		cli.Init()
		cli.Impl = cli
		return cli
	}

	startHTTPServer(srv.httpPort, srv.httpHandler)

	go srv.tcpServer.Run()

	srv.serviceRegister()
	go func() {
		tick := time.NewTicker(time.Second * 1)
		defer func() {
			tick.Stop()
			if err := recover(); err != nil {
				logger.Error("[异常] 全局定时器出错", err, "\n", string(debug.Stack()))
			}
		}()
		for {
			select {
			case <-tick.C:
				srv.timer.Loop()
			}
		}
	}()
}

func (srv *Server) Finialize() {
	req := &common.ReqCenterClose{}
	centerServerInstance().onlineHttpPort.Range(func(key, value any) bool {
		port, ok := value.(int)
		if !ok {
			return true
		}
		_ = common.SendOnlineHttpRequest(req, nil, "/centerClose", port)
		return false
	})
	close(onlineClientMgrGetMe().stop)
	srv.tcpServer.Close()
}

func (srv *Server) serviceRegister() {
	// 注册tcp服务
	srv.tcpSrvID = idgenerator.FetchServiceID(tcpService, srv.tcpSrvAddr)
	logger.Infof("centerTcpServerID:%v", srv.tcpSrvID)
	//
	// 注册服务器内部tcp服务
	srv.httpSrvID = idgenerator.FetchServiceID(httpService, srv.httpAddr)
	logger.Infof("centerHttpServerID:%v", srv.httpSrvID)
}
